﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Odelle.WoWArmory
{
    public class AccessArmory
    {
        #region Properties

        public enum RegionType
        {
            Region_US,
            Region_EU
        }
        public RegionType Region { get; set; }

        public static string[] RegionNames
        {
            get
            {
                return new string[] { "US", "EU" };
            }
        }

        public enum ArmoryCharacterType
        {
            ArmoryCharacter_Character,
            ArmoryCharacter_Simple,
            ArmoryCharacter_Achievement
        }

        #endregion

        #region Constructor / Destructor

        public AccessArmory()
        {
            this.Region = RegionType.Region_US;
        }

        #endregion

        public static string RegionToString(RegionType region)
        {
            switch (region)
            {
                case RegionType.Region_US:
                    return "US";
                case RegionType.Region_EU:
                    return "EU";
                default:
                    return "US";
            }
        }

        public void SetRegion(string region)
        {
            switch (region.ToLower())
            {
                case "us":
                    this.Region = RegionType.Region_US;
                    break;
                case "eu":
                    this.Region = RegionType.Region_EU;
                    break;
                default:
                    this.Region = RegionType.Region_US;
                    break;
            }
        }

        public string FetchArmoryItem(string itemId) // item
        {
            string url = GetBaseUrl(this.Region);

            url = url + @"item/" +  itemId ;

            return FetchHttp(url);
        }

        public string FetchArmoryGuild(string realm, string name, int page)  // guild
        {
            if (page < 1)
                page = 1;

            string url = GetBaseUrl(this.Region);

            url = url + @"guild/" + realm + @"/" +  name + @"/roster" + "?page=" + page.ToString();

            return FetchHttp(url);
        }

        public string FetchArmoryCharacter(string realm, string name)
        {
            return FetchArmoryCharacter(realm, name, ArmoryCharacterType.ArmoryCharacter_Character);
        }

        public string FetchArmoryCharacter(string realm, string name, ArmoryCharacterType dataType) 
        {
            string url = GetBaseUrl(this.Region);

            switch (dataType)
            {
                case ArmoryCharacterType.ArmoryCharacter_Character:
                    url = url + @"character/" + realm + @"/" + name + @"/advanced";
                    break;

                case ArmoryCharacterType.ArmoryCharacter_Simple:
                    url = url + @"character/" + realm + @"/" + name + @"/simple";
                    break;

                case ArmoryCharacterType.ArmoryCharacter_Achievement:
                    url = url + @"character/" + realm + @"/" + name + @"/achievement";
                    break;

                default:
                    url = "error: armory parameter - " + dataType.ToString() + " realm:" + realm + " name:" + name;
                    break;
            }

            return FetchHttp(url);
        }

        private string GetBaseUrl(RegionType region)
        {
            string url = "";

            switch (region)
            {
                case RegionType.Region_US:
                    url = @"http://us.battle.net/wow/en/";
                    break;

                case RegionType.Region_EU:
                    url = @"http://eu.battle.net/wow/en/";
                    break;

                default:
                    url = @"http://us.battle.net/wow/en/";
                    break;
            }

            return url;
        }

        public string FetchHttp(string url)
        {
            if (url.Contains("error: ") || url=="")
            {
                return _getErrorXml("implementation error in the program code", url, "");
            }

            string html = "";

            System.Net.WebClient web = new System.Net.WebClient();
            //web.Headers.Add("User-Agent", @"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");
            //web.Headers.Add("User-Agent", @"Mozilla/4.0 (compatible; Blue Forest; TBC/2.0)");
            //web.Headers.Add("User-Agent", @"Mozilla/4.0 (compatible; Blue Forest; WLK/3.0)");
            //web.Headers.Add("User-Agent", @"Mozilla/5.0 (compatible; Blue Forest; Cata/4.0)");
            web.Headers.Add("User-Agent", @"Mozilla/5.0 (compatible; Blue Forest; Panda/5.0)");

            byte[] htmlData = null;
            try
            {
                htmlData = web.DownloadData(UrlEncode(url));
            }
            catch (Exception e)
            {
                return _getErrorXml("url access error", url, e.Message);
            }

            System.Text.Encoding encode = System.Text.Encoding.UTF8;
            try
            {
                html = encode.GetString(htmlData);
            }
            catch (Exception e)
            {
                return _getErrorXml("html encoding error", url, e.Message);
            }

            return html;
        }

        private string UrlEncode(string url)
        {
            return Uri.EscapeUriString(url);
        }

        private string _getErrorXml(string name, string value, string message)
        {
            System.Xml.XmlDocument xmlerror = new System.Xml.XmlDocument();

            xmlerror.LoadXml(@"<Error name='' value='' message=''/>");
            XmlElement node = xmlerror.DocumentElement;

            node.Attributes.GetNamedItem("name").Value = name;
            node.Attributes.GetNamedItem("value").Value = value;
            node.Attributes.GetNamedItem("message").Value = message;

            return xmlerror.OuterXml;
        }
    }
}
